//
//  SICPSDKBlueToothTool.m
//  test1
//
//  Created by Piccolo on 2017/4/10.
//  Copyright © 2017年 Piccolo. All rights reserved.
//

#import "SICPSDKBlueToothTool.h"
#import "SICPSDKSendSourceRequest.h"
#import "SICPSDKSendRequest.h"
#import "SICPSDKPeripheral.h"
#import "SICPSDKCommon.h"


@interface SICPSDKBlueToothTool()
@property (atomic, strong) NSData *characteristicValueBuffer;
@property (atomic, strong) NSData *activeReportingCharacteristicValueBuffer;
@property (atomic, strong) NSString *peripheralStrBuffer;
@property (atomic, strong) NSString *disconnectedPeripheralStrBuffer;
@property (nonatomic, strong) NSTimer *stopScanTimer;


@end

@implementation SICPSDKBlueToothTool

{
    NSString *_debugStr;
    //系统蓝牙设备管理者
    // 用于保存被发现的设备(外设)
//    CBPeripheral *_peripheral;
//    CBCharacteristic        *_writeCharacteristic;
//    CBCharacteristic        *_readCharacteristic;
    
    BOOL _isFirstVerify;
    int type;
    NSMutableArray *_valueArray;
    NSInteger _testCount;
//    NSData *_communicateKey;
    int _testInt;
}

//实现单例方法
+(instancetype)sharedManager{
    static SICPSDKBlueToothTool *tool = nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        tool = [[self alloc] init];
    });
    return tool;
}


- (void)initBlueToothManager{
    
//    if (_manager == nil || ![_manager isScanning]) {
    if (_manager == nil) {
//        _manager = [[CBCentralManager alloc]initWithDelegate:self queue:dispatch_get_main_queue()];//glo
        
#if  __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_6_0
        NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                                 //蓝牙power没打开时alert提示框
                                 [NSNumber numberWithBool:YES],CBCentralManagerOptionShowPowerAlertKey,
                                 //重设centralManager恢复的IdentifierKey
                                 @"babyBluetoothRestore",CBCentralManagerOptionRestoreIdentifierKey,
                                 nil];
        
#else
        NSDictionary *options = nil;
#endif
        
        NSArray *backgroundModes = [[[NSBundle mainBundle] infoDictionary]objectForKey:@"UIBackgroundModes"];
        if ([backgroundModes containsObject:@"bluetooth-central"]) {
            //后台模式
            _manager = [[CBCentralManager alloc]initWithDelegate:self queue:nil options:options];
        }
        else {
            //非后台模式
            _manager = [[CBCentralManager alloc]initWithDelegate:self queue:nil];
        }
        
        
        
        _smartItPeripheral = [SICPSDKPeripheral new];
    }
//    _manager = [[CBCentralManager alloc]initWithDelegate:self queue:dispatch_get_main_queue()];
    
    _isFirstVerify = YES;

}

- (void)destroyTheKey{
    if (_smartItPeripheral.peripheral ){
        
        [_manager cancelPeripheralConnection:_smartItPeripheral.peripheral];
        _smartItPeripheral = nil;

    }
//    _manager = nil;
    
}

- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
    switch (central.state) {
            
        case CBCentralManagerStateUnknown:
            
            break;
            
        case CBCentralManagerStateResetting:
            
            break;
            
        case CBCentralManagerStateUnsupported:
            
            break;
            
        case CBCentralManagerStateUnauthorized:
           
            break;
            
        case CBCentralManagerStatePoweredOff:
//            [SICPSDKService disConnectBle];
            if ([SICPSDKCommon delegateExist:[SICPSDKService sharedManager].delegate delegate:@protocol(SILightDelegate) selector:@selector(requestBluetoothDisabled)]) {
                [[SICPSDKService sharedManager].delegate requestBluetoothDisabled];
            }
            SICPSDKService.sharedManager.bluetoothIsOn = NO;
            NSLog(@"@sdk蓝牙关闭");
            
            break;
            
        case CBCentralManagerStatePoweredOn:
            
            NSLog(@"@sdk蓝牙打开");
            SICPSDKService.sharedManager.bluetoothIsOn = YES;
            [self startScan];
//            if (![_manager isScanning]){
//                //扫描外设备(第一个参数为nil就是扫描所有的设备)
//                [_manager scanForPeripheralsWithServices:nil options:nil];
//
//            }
            
            
            break;
            
        default:
            
            break;
    }
}

#pragma mark - CBCentralManagerDelegate

- (void)centralManager:(CBCentralManager *)central willRestoreState:(NSDictionary *)state {
//    activePeripheral = [state[CBCentralManagerRestoredStatePeripheralsKey] firstItem];
//    activePeripheral.delegate = self;
//
//    NSString *str = [NSString stringWithFormat: @"%@ %lu", @"Device: ", activePeripheral.UUID];
//    [self sendNotification:str];
}



- (void)connectBle:(SICPSDKPeripheral *)ble{
    [_stopScanTimer invalidate];
    _stopScanTimer = nil;
    [_manager stopScan];
    if (!_smartItPeripheral) {
        _smartItPeripheral = [SICPSDKPeripheral new];
    }
        
    _smartItPeripheral = ble;
    
    //        _peripheral = peripheral;
    [_manager connectPeripheral:_smartItPeripheral.peripheral options:nil];
    _isFirstVerify = YES;

}
- (void)peripheralDidUpdateRSSI:(CBPeripheral *)peripheral error:(NSError *)error{
    if ([SICPSDKCommon delegateExist:[SICPSDKService sharedManager].delegate delegate:@protocol(SILightDelegate) selector:@selector(currentRssi:)]) {
        [[SICPSDKService sharedManager].delegate currentRssi:peripheral.RSSI];
    }
}

- (void)destroyPeripheral{
    if (_smartItPeripheral.peripheral){
        _smartItPeripheral = nil;
    }
}

- (void)startScan{
//    if (_peripheral){
//        [self disconnectBle];
//
//        [self destroyPeripheral];
//        
//        
//    }
//    [_manager stopScan];
//    if (![_manager isScanning]){
        //扫描外设备(第一个参数为nil就是扫描所有的设备)
        [_manager scanForPeripheralsWithServices:nil options:nil];
        NSLog(@"@154开始扫描");

        double delayInSeconds = 3.f;
        
//        [_stopScanTimer invalidate];
        if (_stopScanTimer) {
            [_stopScanTimer invalidate];
            _stopScanTimer = nil;
        }
    dispatch_async(dispatch_get_main_queue(), ^{
        _stopScanTimer = [NSTimer scheduledTimerWithTimeInterval:delayInSeconds target:self selector:@selector(stopScanEvent:) userInfo:nil repeats:NO];

    });
//    }
}

- (void)stopScanEvent:(NSTimer *)timer {
    if ([SICPSDKCommon delegateExist:[SICPSDKService sharedManager].delegate delegate:@protocol(SILightDelegate) selector:@selector(requestStopScanBle)]) {
        [[SICPSDKService sharedManager].delegate requestStopScanBle];
    }
    [self.manager stopScan];
    NSLog(@"@174停止扫描");
}

- (void)stopScan{
//    if (_peripheral){
//        [self disconnectBle];
//
//        [self destroyPeripheral];
//        
//        _peripheral = nil;
//        
//    }
    if ([SICPSDKCommon managerIsScanning:_manager defBool:YES]) {
        [_stopScanTimer invalidate];
        _stopScanTimer = nil;
        [_manager stopScan];
    }
    
    
    
}


- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI
{
    
    NSLog(@"发现附近蓝牙:%@--%@",peripheral.name,peripheral.identifier);
    
    NSString *tmpStr = [NSString stringWithFormat:@"发现附近蓝牙:%@",peripheral.name];
    NSLog(@"@111:%@",tmpStr);
    
    NSString * identityName = [advertisementData objectForKey:CBAdvertisementDataLocalNameKey];
    NSLog(@"@105%@",identityName);
    if (!identityName) {
        identityName = peripheral.name;
    }
    
    if (peripheral.name){
        if ([SICPSDKCommon delegateExist:[SICPSDKService sharedManager].delegate delegate:@protocol(SILightDelegate) selector:@selector(scanedPeripheral:)]) {
            SICPSDKPeripheral *smartItPeripheral = [SICPSDKPeripheral new];
            smartItPeripheral.peripheral = peripheral;
            smartItPeripheral.identityName = identityName;
            [[SICPSDKService sharedManager].delegate scanedPeripheral:smartItPeripheral];
        }
    }
//   dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
//
//        while (_manager) {
//            [_smartItPeripheral.peripheral readRSSI];
//            [NSThread sleepForTimeInterval:0.5f];
//        }
//
//   });
    
    
    

    //    if ([peripheral.name hasPrefix:@"HNTT028B56F4"]) {
    //            if ([peripheral.name hasPrefix:@"Rayonicskey"]) {
//    if ([peripheral.name isEqualToString:@"RayonicsKEY-v001"]) {
//        /*
//         找到设备，并持有他，否则CBCentralManager不会保存peripheral,
//         那么CBPeripheralDelegate中的代理方法也不会被调用
//         */
//        //        [_peripherals addObject:peripheral];
//        [_manager stopScan];
//        _peripheral = peripheral;
//        
//        
//        /*
//         一个主设别最多链接7个外设，每个外设最多只能给一个主设链接
//         链接成功、失败、断开就会进入各自的委托
//         */
//        
//        //链接设备
//        [_manager connectPeripheral:peripheral options:nil];
//        
//    }
}//扫描到设备并过滤外设,进而建立连接

- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
    NSLog(@"链接外设%@成功",peripheral.name);
    _peripheralStrBuffer = peripheral.name;
    
    
    // 设置外设代理
    [peripheral setDelegate:self];
    
    
    // 扫描外设的 services
    [peripheral discoverServices:nil];
    
}// 与外设链接成功

-(void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
    NSLog(@">>>连接到名称为（%@）的设备-失败,原因:%@",[peripheral name],[error localizedDescription]);
}//链接失败


- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
//    _writeCharacteristic = nil;
    
//    [peripheral readValueForCharacteristic:_readCharacteristic];
    peripheral.delegate = nil;
//    NSString *titleStr = [NSString stringWithFormat:@"%@ disconnected",_peripheral.name];
//    [[[UIAlertView alloc] initWithTitle:titleStr message:nil delegate:self cancelButtonTitle:@"ko" otherButtonTitles:nil, nil] show];
    _smartItPeripheral = nil;
    [SICPSDKService disConnectBle];
    NSLog(@">>>外设连接断开连接 %@\nerror : %@\n", [peripheral name], [error localizedDescription]);
    NSString *tempStr = [NSString stringWithFormat:@">>>外设连接断开连接 %@", [peripheral name]];
    _disconnectedPeripheralStrBuffer = peripheral.name;
    NSLog(@"@175:%@",tempStr);
}// 外设断开连接


//发现服务后回调的方法
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
    for (CBService *service in peripheral.services)
    {
        //发现服务 比较服务的UUID
        NSLog(@"Service found with UUID: %@", service.UUID);
        //        [peripheral discoverCharacteristics:nil forService:service];
        
        if ([service.UUID isEqual:[CBUUID UUIDWithString:READ_SERVICE]] || [service.UUID isEqual:[CBUUID UUIDWithString:WRITE_SERVICE]]){
            [peripheral discoverCharacteristics:nil forService:service];
        }
    }
}
//开发服务中的特征值后回调的方法


-(void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
    if (error) {
        NSLog(@"@199:%@",[error localizedDescription]);
    }
    
    /*
     *    读取Characteristic 的值
     *     进入下面代理方法
     *   - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
     *
     */
    if (!_serviceBufferDic) {
        _serviceBufferDic = [[NSMutableDictionary alloc] init];
    }
    if ([service.UUID isEqual:[CBUUID UUIDWithString:READ_SERVICE]]) {
        [_serviceBufferDic setObject:service forKey:@"read_service"];
    }
    if ([service.UUID isEqual:[CBUUID UUIDWithString:WRITE_SERVICE]]) {
        [_serviceBufferDic setObject:service forKey:@"write_service"];
    }
    [_serviceBufferDic setObject:peripheral forKey:@"peripheral"];
    
    
    
    
    /*
     *  读取 Characteristic 的 Descriptors
     *
     */
    
    for (CBCharacteristic *Characteristic in service.characteristics) {
        
        [peripheral discoverDescriptorsForCharacteristic:Characteristic];
    }
    
    
    
    
}//每个服务的特征值

- (NSArray *)getValueOfCharacteristic{
    
    int i = 0;
    if (!_valueArray) {
        _valueArray = [NSMutableArray new];
    }
    _characteristicValueBuffer = [NSData new];
    //    [self printDelay:@"返回监听开始"];
    [_valueArray removeAllObjects];
    
    while (i < 3500){
        
        if (_smartItPeripheral.peripheral.state != CBPeripheralStateConnected) {
            return nil;
        }

        if (_characteristicValueBuffer.length > 0){
            
            NSData *value = [[NSData alloc] initWithData:_characteristicValueBuffer];
            _characteristicValueBuffer = [NSData new];

            Byte *bytes = (Byte *)value.bytes;
            
            NSInteger maxCount = 0;
            
            if (bytes[0]) {
                maxCount = [SICPSDKSendRequest getMaxCountFromCommandWorder:bytes[0]];
            }

//            NSLog(@"@308-------------------%d",i);
            
            [_valueArray addObject:value];
            if (_valueArray.count == maxCount) {
                NSLog(@"@334:count:%ld", _valueArray.count);
//                if (_valueArray.count != 2) {
//                    NSLog(@"@336:%@",value);
//                }
                return _valueArray;
            }
            
        }
        
        [NSThread sleepForTimeInterval:0.001f];
        i++;
    }
    return nil;
    
}






- (NSMutableDictionary *)getValueServiceDic{
    int i = 0;
    
    _serviceBufferDic = nil;
    //    [self printDelay:@"返回监听开始"];
    
    while (i < 3500){
        
        if ([SICPSDKCommon isExistDic:_serviceBufferDic key:@"read_service"] || [SICPSDKCommon isExistDic:_serviceBufferDic key:@"write_service"]){
            
            NSMutableDictionary *value = [_serviceBufferDic copy];
            NSLog(@"@345-------------------%d",i);
            
            if (value){
                return value;
            }
        }
        
        [NSThread sleepForTimeInterval:0.001f];
        i++;
    }
    
    return nil;
    
}

- (NSString *)getConnectedKey{
    
    
    
    int i = 0;
    
    _peripheralStrBuffer = nil;
    //    [self printDelay:@"返回监听开始"];
    CBService *value = nil;
    while (i < 3500){
        
        if (_peripheralStrBuffer){
            
            return _peripheralStrBuffer;
            
        }
        
        [NSThread sleepForTimeInterval:0.001f];
        i++;
    }
    
    if (value == nil){
        
        NSLog(@"connect failed");
    }
    return nil;
    
}

- (NSString *)getDisconnectedKey{
    
    
    
    int i = 0;
    
    //    [self printDelay:@"返回监听开始"];
    CBService *value = nil;
    while (i < 3500){
        
        if (_disconnectedPeripheralStrBuffer){
            NSString *resultBuffer = [_disconnectedPeripheralStrBuffer copy];
            _disconnectedPeripheralStrBuffer = nil;

            return resultBuffer;
            
        }
        if (i % 1000 == 0) {
            NSLog(@"检测中:%d---%@", i, _disconnectedPeripheralStrBuffer);
        }
            
        
        [NSThread sleepForTimeInterval:0.001f];
        i++;
    }
    
    if (value == nil){
        NSLog(@"disconnect failed");
    }
    return nil;
    
}


- (void)disconnectBle{
        
    //断开连接;
    if (_smartItPeripheral.peripheral) {
        
        [_manager cancelPeripheralConnection:_smartItPeripheral.peripheral];

    }

}



//获取的charateristic的值
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
    
    if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:READ_CHARA]]) {
        _testInt ++;
        NSLog(@"@250%@--这是第%d条---读特征值:%@",characteristic.value, _testInt, _readCharacteristic);
        
        NSData *value =characteristic.value;
        Byte *byte = (Byte *)value.bytes;
        
        if (value) {
            if (byte[0] == 0x10) {
//                NSLog(@"@这里收到1");
            }
            if (byte[0] == NSSIBluetoothReceiveTypeCurrentDeviceStatus) {
                _activeReportingCharacteristicValueBuffer = value;
            }
            else{
                _characteristicValueBuffer = value;
            }
        }
    }
}


- (void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(nonnull CBCharacteristic *)characteristic error:(nullable NSError *)error
{
    for (CBDescriptor *des in characteristic.descriptors) {
//        NSLog(@"@260%@",des.value);
    }
    
}//搜索到Characteristic的Descriptors



-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForDescriptor:(CBDescriptor *)descriptor error:(NSError *)error
{
    
    //这个descriptor都是对于characteristic的描述，一般都是字符串，所以这里我们转换成字符串去解析
    NSLog(@"@273characteristic uuid:%@  value:%@",[NSString stringWithFormat:@"%@",descriptor.UUID],descriptor.value);
    
}//获取 Descriptors的值

-(void)writeCharacteristic:(CBPeripheral *)peripheral
            characteristic:(CBCharacteristic *)characteristic
                     value:(NSData *)value
{
    
    //打印出 characteristic 的权限，可以看到有很多种，这是一个NS_OPTIONS，就是可以同时用于好几个值，常见的有read，write，notify，indicate，知知道这几个基本就够用了，前连个是读写权限，后两个都是通知，两种不同的通知方式。
    /*
     typedef NS_OPTIONS(NSUInteger, CBCharacteristicProperties) {
     CBCharacteristicPropertyBroadcast                                              = 0x01,
     CBCharacteristicPropertyRead                                                   = 0x02,
     CBCharacteristicPropertyWriteWithoutResponse                                   = 0x04,
     CBCharacteristicPropertyWrite                                                  = 0x08,
     CBCharacteristicPropertyNotify                                                 = 0x10,
     CBCharacteristicPropertyIndicate                                               = 0x20,
     CBCharacteristicPropertyAuthenticatedSignedWrites                              = 0x40,
     CBCharacteristicPropertyExtendedProperties                                     = 0x80,
     CBCharacteristicPropertyNotifyEncryptionRequired NS_ENUM_AVAILABLE(NA, 6_0)        = 0x100,
     CBCharacteristicPropertyIndicateEncryptionRequired NS_ENUM_AVAILABLE(NA, 6_0)  = 0x200
     };
     
     */
    NSLog(@"%lu", (unsigned long)characteristic.properties);
    
    
    //只有 characteristic.properties 有write的权限才可以写
    if(characteristic.properties & CBCharacteristicPropertyWrite){
        /*
         最好一个type参数可以为CBCharacteristicWriteWithResponse或type:CBCharacteristicWriteWithoutResponse,区别是是否会有反馈
         */
        [peripheral writeValue:value forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse];
    }else{
        NSLog(@"该字段不可写！");
    }
    
    
}//写数据

-(void)notifyCharacteristic:(CBPeripheral *)peripheral characteristic:(CBCharacteristic *)characteristic
{
    
    //设置通知，数据通知会进入：didUpdateValueForCharacteristic方法
    [peripheral setNotifyValue:YES forCharacteristic:characteristic];
    
}//设置通知

- (void)notify:(CBPeripheral *)peripheral characteristic:(CBCharacteristic *)characteristic block:(void(^)(CBPeripheral *peripheral, CBCharacteristic *characteristics, NSError *error))block {
    //设置通知
    [peripheral setNotifyValue:YES forCharacteristic:characteristic];
}

-(void)cancelNotifyCharacteristic:(CBPeripheral *)peripheral characteristic:(CBCharacteristic *)characteristic
{
    
    [peripheral setNotifyValue:NO forCharacteristic:characteristic];
    
}//取消通知

- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral{
    
}


-(void)disconnectPeripheral:(CBCentralManager *)centralManager peripheral:(CBPeripheral *)peripheral
{
    
    
    //停止扫描
    [centralManager stopScan];
    
    //断开连接;
    [centralManager cancelPeripheralConnection:peripheral];
    
}// 停止扫描和断开连接

-(void)updateNsLog:(NSString *)s
{
    NSString *str = [NSString stringWithFormat:@"%@\r\n%@",_debugStr,s];
    _debugStr = str;
    
    NSLog(@"@509:%@",s);
}



-(void)writeData:(NSData *)data{
//    NSDictionary *option = @{@"123":@123};
//    NSData *messageData = [SICPSDKSendSourceRequest sendRequestWithSmartITBluetoothSendType:MessageSetKeyId withOption:option];
    [_smartItPeripheral.peripheral writeValue:data forCharacteristic:_writeCharacteristic type:CBCharacteristicWriteWithoutResponse];
    
}

- (void)startDetectActiveReportingValueOfCharacteristic{
    int i = 0;
    NSData *value = [[NSData alloc] init];
    NSLog(@"@587开始监听了哥们");
    
    while (_smartItPeripheral.peripheral.state == CBPeripheralStateConnected){
        
        if (_activeReportingCharacteristicValueBuffer.length > 0){
            
            value = [_activeReportingCharacteristicValueBuffer copy];
            
            //            NSLog(@"@308-------------------%d",i);
            
            if ([value length] > 0){
                
                [SICPSDKSendRequest setActiveReportingValueOfCharacteristic:value];
//                value = nil;
                _activeReportingCharacteristicValueBuffer = [NSData new];
//                [NSThread sleepForTimeInterval:0.01f];
                
            }
            
        }
        
        [NSThread sleepForTimeInterval:0.001f];
        i++;
    }
}



//- (void)printDelay:(NSString *)str{
//    NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
//    [dateFormatter setDateFormat:@"mm:ss:SSS"];
//    // or @"yyyy-MM-dd hh:mm:ss a" if you prefer the time with AM/PM
//    NSLog(@"%@",[dateFormatter stringFromDate:[NSDate date]]);
////    NSString *str = @"主线毫秒打印@";
//    str = [str stringByAppendingString:[dateFormatter stringFromDate:[NSDate date]]];
//    [self.delegate updateDelayTime:str];
//}

@end
